//
//  SwiftStd+YHExtension.swift
//  Adorbee
//
//  Created by amovision on 2025/3/5.
//

import Foundation

public extension Array {
  func classify(by condition: (Element, Element) -> Bool) -> [[Element]] {
    var result: [[Element]] = []
    guard !self.isEmpty else {
      return result
    }
        
    var currentSubarray: [Element] = [self[0]]
    for i in 1..<self.count {
      let currentElement = self[i]
      let previousElement = self[i - 1]
      if condition(previousElement, currentElement) {
        currentSubarray.append(currentElement)
      } else {
        result.append(currentSubarray)
        currentSubarray = [currentElement]
      }
    }
    result.append(currentSubarray)
    return result
  }
    
  func classifyById<U: Comparable>(_ feature: (Element) -> U, ascending: Bool = true) -> [[Element]] {
    var result: [[Element]] = []
    guard !self.isEmpty else { return result }
    let sortedArray = sorted {
      if ascending {
        feature($0) < feature($1)
      } else {
        feature($0) > feature($1)
      }
    }
    var currentFeature = feature(sortedArray[0])
    var currentSubarray: [Element] = [sortedArray[0]]
    for i in 1..<sortedArray.count {
      let element = sortedArray[i]
      let elementFeature = feature(element)
      if elementFeature == currentFeature {
        currentSubarray.append(element)
      } else {
        result.append(currentSubarray)
        currentSubarray = [element]
        currentFeature = elementFeature
      }
    }
    result.append(currentSubarray)
    return result
  }
    
  func classifyById<U: Equatable>(_ feature: (Element) -> U) -> [[Element]] {
    var result: [[Element]] = []
    guard !self.isEmpty else { return result }
    var currentFeature = feature(self[0])
    var currentSubarray: [Element] = [self[0]]
    for i in 1..<self.count {
      let element = self[i]
      let elementFeature = feature(element)
      if elementFeature == currentFeature {
        currentSubarray.append(element)
      } else {
        result.append(currentSubarray)
        currentSubarray = [element]
        currentFeature = elementFeature
      }
    }
    result.append(currentSubarray)
    return result
  }
}
